package main
/**
闭包的使用2
 */
import "fmt"

type CalcFunc func(x, y int) int

func AddFunc(x, y int) int {
	return x + y
}

func SubFunc(x, y int) int {
	return x - y
}

func OperationFunc(x, y int, calcFunc CalcFunc) int {
	return calcFunc(x, y)
}

//多func返回1
func calc(x, y int) (func(int) int, func() int)  {
	f1 := func(z int) int {
		return (x + y) * z / 2
	}

	f2 := func() int {
		return 2 * (x + y)
	}
	return f1, f2
}

//多func返回2
func counter(start int) (func() int, func()) {
	ctr := func() int {
		return start
	}
	incr := func() {
		start++
	}
	return ctr, incr
}

//斐波拉切数列
func fibonacci() func() int {
	x, y := 0, 1
	return func() int {
		x, y = y, x+y
		return x
	}
}

func main() {
	sum := OperationFunc(1, 2, AddFunc)
	difference := OperationFunc(1, 2, SubFunc)

	fmt.Println(sum)
	fmt.Println(difference)

	f1, f2 := calc(2, 3)
	n1 := f1(10)
	n2 := f1(20)
	n3 := f2()
	fmt.Println("n1, n2, n3:", n1, n2, n3)

	safeHandler()

	ctr, incr := counter(100)
	ctr1, incr1 := counter(100)
	fmt.Println("counter - ", ctr())
	fmt.Println("counter1 - ", ctr1())
	// incr by 1
	incr()
	fmt.Println("counter - ", ctr())
	fmt.Println("counter1- ", ctr1())
	// incr1 by 2
	incr1()
	incr1()
	fmt.Println("counter - ", ctr())
	fmt.Println("counter1- ", ctr1())

	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}

func safeHandler() {
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println("some exception has happend:", err)
		}
	}()
}
/**
运行结果：
$ go run closures-adv.go
3
-1
n1, n2, n3: 25 50 10
counter -  100
counter1 -  100
counter -  101
counter1-  100
counter -  101
counter1-  102
1
1
2
3
5
8
13
21
34
55
 */